<template>
  <el-button v-if="props.type == 'add'" type="primary" icon="plus" plain @click="handlePublish()">{{
    $t("button.publish")
  }}</el-button>
  <!-- 这里需要el-tooltip，需要确保组件模板有一个有效的根元素 -->
  <el-tooltip v-if="props.type == 'update'" :content="$t('button.update')" placement="top">
    <el-button type="primary" icon="Edit" circle plain @click="handleUpdate()" v-auth="['blog:article:update']"></el-button>
  </el-tooltip>

  <!-- 添加 OR 修改 -->
  <KoiDialog ref="koiDialogRef" :title="title" @koiConfirm="handleConfirm" @koiCancel="handleCancel" fullscreen footerHidden>
    <template #header>
      <el-affix :offset="20" style="width: 100%">
        <div class="flex h-46px">
          <!-- 靠右对齐 -->
          <div class="m-l-auto">
            <el-button type="danger" plain @click="handleCancel">
              <el-icon class="m-r-5px">
                <Close></Close>
              </el-icon>
              {{ $t("button.cancel") }}
            </el-button>

            <el-button type="primary" plain @click="handleConfirm">
              <el-icon class="m-r-5px">
                <Select></Select>
              </el-icon>
              {{ $t("button.publish") }}
            </el-button>
          </div>
        </div>
      </el-affix>
    </template>
    <template #content>
      <el-form ref="formRef" :rules="rules" :model="form" label-width="auto" label-position="top" status-icon>
        <el-row>
          <el-col :sm="{ span: 24 }" :xs="{ span: 24 }">
            <el-form-item label="文章标题" prop="articleTitle">
              <el-input v-model="form.articleTitle" placeholder="请输入文章标题" show-word-limit maxlength="128" clearable />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :xs="{ span: 24 }">
            <el-form-item label="文章内容" prop="content">
              <!-- Md-Editor-V3官网文档 https://imzbf.github.io/md-editor-v3/zh-CN/docs -->
              <MdEditor
                v-model="form.content"
                :editorId="editorId"
                :theme="globalStore.isDark ? 'dark' : 'light'"
                :previewTheme="globalStore.previewTheme"
                :codeTheme="globalStore.codeTheme"
                :scrollElement="scrollElement"
                @onUploadImg="handleUploadImage"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 12 }" :xs="{ span: 24 }">
            <el-form-item label="文章图片" prop="picture">
              <!-- 方形示例 -->
              <KoiUploadImage v-model:imageUrl="form.picture" width="214px">
                <template #content>
                  <el-icon><Picture /></el-icon>
                  <span>请上传图片</span>
                </template>
                <template #tip>图片最大为 3M</template>
              </KoiUploadImage>
            </el-form-item>
          </el-col>
          <el-col :sm="{ span: 12 }" :xs="{ span: 24 }" class="p-l-10px">
            <el-form-item label="图片地址" prop="picture">
              <el-input v-model="form.picture" :rows="5" type="textarea" placeholder="请输入网络图片地址" clearable />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 24 }" :xs="{ span: 24 }">
            <el-form-item label="文章描述" prop="remark">
              <el-input
                v-model="form.remark"
                :rows="5"
                type="textarea"
                placeholder="请输入文章描述"
                show-word-limit
                maxlength="256"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="文章类别" prop="categoryId">
              <el-select v-model="form.categoryId" clearable filterable placeholder="请选择文章类别">
                <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="文章标签" prop="tagIds">
              <el-select
                v-model="form.tagIds"
                multiple
                collapse-tags
                collapse-tags-tooltip
                clearable
                :multiple-limit="3"
                :max-collapse-tags="3"
                placeholder="请选择文章标签[最多三个]"
              >
                <el-option v-for="item in tagOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="文章类型" prop="articleType">
              <el-select placeholder="请选择文章类型" v-model="form.articleType" clearable>
                <el-option
                  v-for="koi in koiDicts.blog_article_type"
                  :key="koi.dictValue"
                  :label="koi.dictLabel"
                  :value="koi.dictValue"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="是否推荐" prop="isCommend">
              <el-select placeholder="请选择是否推荐" v-model="form.isCommend" clearable>
                <el-option
                  v-for="koi in koiDicts.sys_yes_no"
                  :key="koi.dictValue"
                  :label="koi.dictLabel"
                  :value="koi.dictValue"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="是否热门" prop="isHot">
              <el-select placeholder="请选择是否热门" v-model="form.isHot" clearable>
                <el-option
                  v-for="koi in koiDicts.sys_yes_no"
                  :key="koi.dictValue"
                  :label="koi.dictLabel"
                  :value="koi.dictValue"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="浏览数" prop="views">
              <el-input-number v-model="form.views" clearable style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="文章作者" prop="createBy">
              <el-input v-model="form.createBy" placeholder="请输入文章作者" clearable />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="排序" prop="sorted">
              <el-input-number v-model="form.sorted" clearable style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :sm="{ span: 10 }" :xs="{ span: 24 }">
            <el-form-item label="文章状态" prop="articleStatus">
              <el-select placeholder="请选择文章状态" v-model="form.articleStatus" clearable>
                <el-option
                  v-for="koi in koiDicts.sys_switch_status"
                  :key="koi.dictValue"
                  :label="koi.dictLabel"
                  :value="koi.dictValue"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <!-- {{ form }} -->
    </template>
  </KoiDialog>
</template>

<script setup lang="ts">
import { nextTick, ref, reactive, defineEmits } from "vue";
import { koiMsgSuccess, koiMsgError, koiMsgWarning } from "@/utils/koi.ts";
import koi from "@/utils/axios.ts";
import { MdEditor } from "md-editor-v3";
import "md-editor-v3/lib/style.css";
import { listTagElSelect } from "@/api/blog/tag/index.ts";
import { listCategoryElSelect } from "@/api/blog/category/index.ts";
import { getSorted, publish, echoById, update } from "@/api/blog/article/index.ts";
import { ElLoading } from "element-plus";
import { useI18n } from "vue-i18n";
import { useKoiDict } from "@/hooks/dicts/index.ts";
import useGlobalStore from "@/stores/modules/global.ts";

const { koiDicts } = useKoiDict(["blog_article_type", "sys_switch_status", "sys_yes_no"]);
const { t } = useI18n();
// 子组件调用父组件方法
const $emit = defineEmits(["refresh"]);

// 定义参数的类型
interface IPublishProps {
  type?: string;
  articleId?: any;
}

const props = withDefaults(defineProps<IPublishProps>(), {
  type: "add",
  articleId: undefined
});

// Md-Editor-V3 跟 管理平台明亮暗黑模式 同步
const globalStore = useGlobalStore();
const editorId = ref("KOI-MD-ARTICLE-PUBLISH-EDITOR");
const scrollElement = document.documentElement;

// 添加 OR 修改对话框Ref
const koiDialogRef = ref();
// form表单Ref
const formRef = ref<any>();

// form表单
let form = ref<any>({
  articleId: undefined,
  articleTitle: undefined,
  categoryId: undefined,
  tagIds: [],
  isComment: "1",
  isHot: "1",
  views: 1,
  content: undefined,
  picture: undefined,
  sorted: null,
  articleType: "1",
  articleStatus: "0",
  createBy: "于心",
  remark: undefined
});

/** 清空表单数据 */
const resetForm = () => {
  // 等待 DOM 更新完成
  nextTick(() => {
    if (formRef.value) {
      // 重置该表单项，将其值重置为初始值，并移除校验结果
      formRef.value.resetFields();
    }
  });
  form.value = {
    articleId: undefined,
    articleTitle: undefined,
    categoryId: undefined,
    tagIds: [],
    isCommend: "1",
    isHot: "1",
    views: 1,
    content: undefined,
    picture: undefined,
    articleStatus: "0",
    sorted: null,
    articleType: "1",
    createBy: "于心",
    remark: undefined
  };
};

/** 表单规则 */
const rules = reactive({
  articleTitle: [
    { required: true, message: "请输入文章标题", trigger: "blur" },
    { min: 1, max: 128, message: "请输入1-128个字符", trigger: "blur" }
  ],
  categoryId: [{ required: true, message: "请选择文章类别", trigger: "blur" }],
  tagIds: [{ required: true, message: "请输入选择文章标签", trigger: "blur" }],
  picture: [{ required: true, message: "请上传图片 或 输入网络图片", trigger: "blur" }],
  articleStatus: [{ required: true, message: "请选择文章状态", trigger: "blur" }],
  articleType: [{ required: true, message: "请选择文章类型", trigger: "blur" }],
  isCommend: [{ required: true, message: "请选择是否推荐", trigger: "blur" }],
  isHot: [{ required: true, message: "请选择是否热门", trigger: "blur" }],
  views: [{ required: true, message: "请输入浏览数", trigger: "blur" }],
  createBy: [{ required: true, message: "请输入文章作者", trigger: "blur" }],
  sorted: [{ required: true, message: "请输入排序序号", trigger: "blur" }],
  remark: [
    { required: true, message: "请输入文章描述", trigger: "blur" },
    { min: 1, max: 256, message: "请输入1-256个字符", trigger: "blur" }
  ]
});

// 文章类别下拉框
const categoryOptions = ref();

/** 文章类别下拉框 */
const handleCategoryElSelect = async () => {
  try {
    categoryOptions.value = [];
    const res: any = await listCategoryElSelect();
    categoryOptions.value = res.data;
  } catch (error) {
    console.log(error);
    koiMsgError(t("msg.fail"));
  }
};

// 文章标签多选下拉框
const tagOptions = ref();

/** 文章标签多选下拉框 */
const handleTagElSelect = async () => {
  try {
    tagOptions.value = [];
    const res: any = await listTagElSelect();
    tagOptions.value = res.data;
  } catch (error) {
    console.log(error);
    koiMsgError(t("msg.fail"));
  }
};

/** 获取最新排序数字 */
const handleSorted = async () => {
  try {
    const res: any = await getSorted();
    form.value.sorted = res.data;
  } catch (error) {
    console.log(error);
    koiMsgError(t("msg.fail"));
  }
};

const title = ref();

/** 发布 */
const handlePublish = () => {
  // 打开对话框
  koiDialogRef.value.koiOpen();
  // 重置表单
  resetForm();
  // 标题
  title.value = "发布文章";
  handleCategoryElSelect();
  handleTagElSelect();
  handleSorted();
};

/** 取消 */
const handleCancel = () => {
  koiDialogRef.value.koiClose();
};

/** 回显数据 */
const handleEcho = async (id: any) => {
  if (id == null || id == "") {
    koiMsgWarning(t("msg.selectData"));
    return;
  }
  try {
    const res: any = await echoById(id);
    form.value = res.data;
  } catch (error) {
    console.log(error);
    koiMsgError(t("msg.fail"));
  }
};

/** 修改 */
const handleUpdate = async () => {
  // 重置表单
  resetForm();
  // 标题
  title.value = t("button.update");
  if (props.articleId == null || props.articleId == "") {
    koiMsgWarning(t("msg.selectData"));
    return;
  }
  handleCategoryElSelect();
  handleTagElSelect();
  // 回显数据
  handleEcho(props.articleId);
  koiDialogRef.value.koiOpen();
};

/** 确认发布  */
const handleConfirm = () => {
  if (!formRef.value) return;
  (formRef.value as any).validate(async (valid: any) => {
    if (valid) {
      const loading = ElLoading.service({
        lock: true,
        text: "正在发布中...",
        background: "rgba(0, 0, 0, 0.7)"
      });
      if (props.articleId != null && props.articleId != "") {
        try {
          form.value.articleId = props.articleId;
          await update(form.value);
          koiMsgSuccess(t("msg.success"));
          koiDialogRef.value.koiQuickClose();
          resetForm();
          loading.close();
        } catch (error) {
          loading.close();
          console.log(error);
          koiMsgError(t("msg.fail"));
        }
      } else {
        try {
          // 发布文章
          await publish(form.value);
          koiMsgSuccess(t("msg.success"));
          loading.close();
          // 快速关闭
          koiDialogRef.value.koiQuickClose();
        } catch (error) {
          loading.close();
          console.log(error);
          koiMsgError(t("msg.fail"));
        }
      }
      $emit("refresh");
    } else {
      koiMsgError(t("msg.validFail"));
    }
  });
};

/** MarkDown上传图片 */
const handleUploadImage = async (files: any, callback: any) => {
  // @ts-ignore
  const res = await Promise.all(
    files.map((file: any) => {
      // @ts-ignore
      return new Promise(async (rev: any, rej: any) => {
        let formData = new FormData();
        formData.append("file", file);
        const res: any = await koi.post("/koi/file/uploadFile/10/markdown/markdown", formData);
        // 调用 callback 函数，回显上传图片
        callback([import.meta.env.VITE_SERVER + res.data.fileUploadPath]);
      });
    })
  );
};
</script>

<style scoped>
/* markdown 脚部高度 */
:deep(.md-editor-footer) {
  height: 36px;
}
</style>
